/* //device/system/broncho-ril/reference-ril.c
**
** Copyright 2006, The Android Open Source Project
**
** Licensed under the Apache License, Version 2.0 (the "License");
** you may not use this file except in compliance with the License.
** You may obtain a copy of the License at
**
**     http://www.apache.org/licenses/LICENSE-2.0
**
** Unless required by applicable law or agreed to in writing, software
** distributed under the License is distributed on an "AS IS" BASIS,
** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
** See the License for the specific language governing permissions and
** limitations under the License.
*/

#include <telephony/ril.h>
#include <stdio.h>
#include <assert.h>
#include <string.h>
#include <errno.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <pthread.h>
#include <alloca.h>
#include "atchannel.h"
#include "at_tok.h"
#include "ril_util.h"
#include <getopt.h>
#include "broncho-ril.h"

#define LOG_TAG "RIL"
#include "broncho_log.h"

static void requestGsmsSmsBroadcastActivation(RIL* thiz, void *data, size_t datalen, RIL_Token t)
{
	/*TODO: */
	RIL_onRequestComplete(thiz, t, RIL_E_REQUEST_NOT_SUPPORTED, NULL, 0);
	return;
}

static void requestGsmSetBroadcastSmsConfig(RIL* thiz, void *data, size_t datalen, RIL_Token t)
{
	/*TODO: */
	RIL_onRequestComplete(thiz, t, RIL_E_REQUEST_NOT_SUPPORTED, NULL, 0);
	return;
}

static void requestGsmGetBroadcastSmsConfig(RIL* thiz, void *data, size_t datalen, RIL_Token t)
{
	/*TODO: */
	RIL_onRequestComplete(thiz, t, RIL_E_REQUEST_NOT_SUPPORTED, NULL, 0);
	return;
}

static void requestSetSmscAddress(RIL* thiz, void *data, size_t datalen, RIL_Token t)
{
	char* smsc = (char*)data;
	char cmd[128] = {0};
	
	snprintf(cmd, 128, "AT+CSCA=%s", smsc);
	if(ril_command_exec_for_result(thiz, cmd))
	{
		RIL_onRequestComplete(thiz, t, RIL_E_SUCCESS, NULL, 0);
	}
	else
	{
		RIL_onRequestComplete(thiz, t, RIL_E_GENERIC_FAILURE, NULL, 0);
	}

	return;
}

static void requestGetSmscAddress(RIL* thiz, void *data, size_t datalen, RIL_Token t)
{
	ATResponse *p_resp = NULL;

	if(ril_command_exec_singleline_for_result(thiz, "AT+CSCA?", "+CSCA:", &p_resp))
	{
		char* smsc = NULL;
		at_line_scanf_string(p_resp->p_intermediates->line, &smsc);
		RIL_onRequestComplete(thiz, t, RIL_E_SUCCESS, smsc, sizeof(char*));
	}
	else
	{
		RIL_onRequestComplete(thiz, t, RIL_E_GENERIC_FAILURE, NULL, 0);
	}
	at_response_free(p_resp);

	return;
}

static void requestDeleteSmsOnSim(RIL* thiz, void *data, size_t datalen, RIL_Token t)
{
	char * cmd = NULL;

	asprintf(&cmd, "AT+CMGD=%d", ((int *)data)[0]);
	if(ril_command_exec_for_result(thiz, cmd))
	{
		RIL_onRequestComplete(thiz, t, RIL_E_SUCCESS, NULL, 0);
	} 
	else 
	{
		RIL_onRequestComplete(thiz, t, RIL_E_GENERIC_FAILURE, NULL, 0);
	}
	free (cmd);

	return;
}

static void requestWriteSmsToSim(RIL* thiz, void *data, size_t datalen, RIL_Token t)
{
    RIL_SMS_WriteArgs *p_args = NULL;
    char *cmd = NULL;
	char* pdu = NULL;
	const char* smsc = NULL;
    int length = 0;
    int err = 0;
    ATResponse *p_response = NULL;

    p_args = (RIL_SMS_WriteArgs *)data;

    length = strlen(p_args->pdu)/2;
    asprintf(&cmd, "AT+CMGW=%d,%d", length, p_args->status);
	smsc = (p_args->smsc == NULL) ? "00" : p_args->smsc;
	asprintf(&pdu, "%s%s", smsc, p_args->pdu);

    if ((err = ril_send_command_sms(thiz, cmd, pdu, "+CMGW:", &p_response)) >= 0
		&& p_response->success != 0)
	{
		int id = 0;

		at_line_scanf_int(p_response->p_intermediates->line, &id);
		RIL_onRequestComplete(thiz, t, RIL_E_SUCCESS, &id, sizeof (int));
	}
	else
	{
		RIL_onRequestComplete(thiz, t, RIL_E_GENERIC_FAILURE, NULL, 0);
	}
	free(pdu);
	free(cmd);
    at_response_free(p_response);

	return;
}

static void requestSendSMS(RIL* thiz, void *data, size_t datalen, RIL_Token t)
{
    int err;
    const char *smsc;
    const char *pdu;
    int tpLayerLength;
    char *cmd1, *cmd2;
    RIL_SMS_Response response;
    ATResponse *p_response = NULL;

    smsc = ((const char **)data)[0];
    pdu = ((const char **)data)[1];

    tpLayerLength = strlen(pdu)/2;

    if (smsc == NULL) {
        smsc= "00";
    }
    asprintf(&cmd1, "AT+CMGS=%d", tpLayerLength);
    asprintf(&cmd2, "%s%s", smsc, pdu);
    if ((err = ril_send_command_sms(thiz, cmd1, cmd2, "+CMGS:", &p_response)) >= 0 
		&& p_response->success != 0)
	{
	    memset(&response, 0, sizeof(response));
		at_line_scanf_int(p_response->p_intermediates->line, &response.messageRef);

	    RIL_onRequestComplete(thiz, t, RIL_E_SUCCESS, &response, sizeof(response));
	}
	else
	{
		RIL_onRequestComplete(thiz, t, RIL_E_GENERIC_FAILURE, NULL, 0);
	}
	at_response_free(p_response);
	free(cmd1);
	free(cmd2);

	return;
}

static void requestSMSAcknowledge(RIL* thiz, void *data, size_t datalen, RIL_Token t)
{
    int ackSuccess = 0;
	char* cmd = NULL;

    ackSuccess = ((int *)data)[0];
    if (ackSuccess == 1) {
		cmd = "AT+CNMA=1";
    } 
	else
	{
		cmd = "AT+CNMA=2";
    } 

	if (ril_command_exec_for_result(thiz, cmd))
	{
	    RIL_onRequestComplete(thiz, t, RIL_E_SUCCESS, NULL, 0);
	}
	else
	{
	    RIL_onRequestComplete(thiz, t, RIL_E_GENERIC_FAILURE, NULL, 0);
	}
	
	return;
}

int RIL_initialize_sms (RIL* thiz)
{
	ril_send_command(thiz, "AT+CMGF=0", NULL);
	/* broncho modify begin by yinlijun*/
	//ril_send_command(thiz, "AT+CNMI=1,2,2,1,0", NULL);
	ril_send_command(thiz, "AT+CNMI=2,2,0,0,0", NULL);
	ril_send_command(thiz, "AT+CMMS=2", NULL);
	/* broncho mofidy end */
	
	return 1;
}

int RIL_onUnsolicited_sms (RIL* thiz, const char* s, const char* sms_pdu)
{
	int ret = 1;

	if (strStartsWith(s, "+CMT:")) 
	{
        RIL_onUnsolicitedResponse(thiz, RIL_UNSOL_RESPONSE_NEW_SMS,
            sms_pdu, strlen(sms_pdu));
    } 
	else if (strStartsWith(s, "+CDS:")) 
	{
        RIL_onUnsolicitedResponse(thiz, RIL_UNSOL_RESPONSE_NEW_SMS_STATUS_REPORT,
            sms_pdu, strlen(sms_pdu));
	}
	else if(strStartsWith(s, "+CBM:"))
	{
		RIL_onUnsolicitedResponse(thiz, RIL_UNSOL_RESPONSE_NEW_BROADCAST_SMS,
			sms_pdu, strlen(sms_pdu));
	}
	else 
	{
		ret = 0;
	}

	return ret;
}

int RIL_onRequest_sms (RIL* thiz, int request, void *data, size_t datalen, RIL_Token t)
{
	switch (request)
	{
	case RIL_REQUEST_SEND_SMS:
		requestSendSMS(thiz, data, datalen, t);
		break;
	
	case RIL_REQUEST_SMS_ACKNOWLEDGE:
		RIL_onRequestComplete(thiz, t, RIL_E_REQUEST_NOT_SUPPORTED, NULL, 0);
		//requestSMSAcknowledge(thiz, data, datalen, t);
		break;

	case RIL_REQUEST_WRITE_SMS_TO_SIM:
		requestWriteSmsToSim(thiz, data, datalen, t);
		break;

	case RIL_REQUEST_DELETE_SMS_ON_SIM:
		requestDeleteSmsOnSim(thiz, data, datalen, t);
		break;

	case RIL_REQUEST_GET_SMSC_ADDRESS:
		requestGetSmscAddress(thiz, data, datalen, t);
		break;

	case RIL_REQUEST_SET_SMSC_ADDRESS:
		requestSetSmscAddress(thiz, data, datalen, t);
		break;

	case RIL_REQUEST_GSM_SMS_BROADCAST_ACTIVATION:
		requestGsmsSmsBroadcastActivation(thiz, data, datalen, t);
		break;

	case RIL_REQUEST_GSM_SET_BROADCAST_SMS_CONFIG:
		requestGsmSetBroadcastSmsConfig(thiz, data, datalen, t);
		break;

	case RIL_REQUEST_GSM_GET_BROADCAST_SMS_CONFIG:
		requestGsmGetBroadcastSmsConfig(thiz, data, datalen, t);
		break;

	case RIL_REQUEST_SEND_SMS_EXPECT_MORE:
	case RIL_REQUEST_REPORT_SMS_MEMORY_STATUS:
	default:
		RIL_onRequestComplete(thiz, t, RIL_E_REQUEST_NOT_SUPPORTED, NULL, 0);
		break;
	}

	return 1;
}

